home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------*/
- /* */
- /* MC68000 Cross Assembler */
- /* */
- /* Copyright (c) 1985 by Brian R. Anderson */
- /* */
- /* Assembler directive processing - November 1, 1989 */
- /* */
- /* This program may be copied for personal, non-commercial use */
- /* only, provided that the above copyright notice is included */
- /* on all copies of the source code. Copying for any other use */
- /* without the consent of the author is prohibited. */
- /* */
- /*------------------------------------------------------------------*/
- /* */
- /* Originally published (in Modula-2) in */
- /* Dr. Dobb's Journal, April, May, and June 1986. */
- /* */
- /* AmigaDOS conversion copyright 1989 by Charlie Gibbs. */
- /* */
- /*------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include "A68kdef.h"
- #include "A68kglb.h"
-
- /* Functions */
- extern int LineParts(), Instructions();
- extern int GetInstModeSize(), GetMultReg(), CountNest();
- extern int ReadSymTab(), GetArgs(), GetAReg(), OpenIncl();
- extern long AddrBndW(), AddrBndL(), GetValue(), CalcValue();
- extern char *AddName(), *GetField();
- extern struct SymTab *NextSym();
- extern struct SymTab **HashIt();
-
-
-
- int ObjDir (dummy) int dummy;
- /* Generates Object Code for Assembler Directives. */
- {
- register char *s, *t;
- register int i, j;
- int oploc;
- long templong;
- char tempop[MAXLINE], delim;
- struct SetFixup *sf;
-
- switch (Dir) {
-
- case Org: /* ORG, RORG */
- PrntAddr = MakeHunk = TRUE;
- FwdLim1 = FwdBranch; /* Clear forward branch controls. */
- FwdFixLimit = FwdBranchFix;
- templong = GetValue (SrcOp, SrcLoc);
- if (DefLine2 >= LineCount) {
- Error (SrcLoc, FwdRef); /* Illegal forward reference */
- break;
- }
- if (OpCode[0] == 'R') { /* RORG */
- if (Hunk2 != ABSHUNK) {
- Error (SrcLoc, RelErr); /* RORG needs an absolute value. */
- break;
- }
- } else if (Hunk2 != CurrHunk) {
- Error (SrcLoc, RelErr); /* We can't ORG out of a hunk. */
- break;
- }
-
- if ((!Pass2 || (HunkType == HunkBSS))
- && (templong < AddrCnt) /* If we're ORGing to a lower address */
- && (AddrCnt > OrgHigh)) /* and this is the highest we've been */
- OrgHigh = AddrCnt; /* remember how far we got. */
-
- AddrCnt = templong; /* Update the location counter. */
- OrgFlag = TRUE; /* Indicate object fixups are needed. */
- break;
-
- case Equ: /* EQU */
- if (Label[0] == '\0')
- Error (0, NeedLab); /* We need a label. */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (DefLine2 >= LineCount)
- Error (SrcLoc, FwdRef); /* Illegal forward reference */
- Src.Hunk = Hunk2;
- PrntAddr = MakeHunk = TRUE;
- break;
-
- case DC: /* DC */
- if ((Size == Word) || (Size == Long))
- AddrCnt = AddrBndW (AddrCnt);
- s = Line + SrcLoc;
- while (!isspace(*s) && (*s != '\0') && (*s != ';')) {
- oploc = s - Line;
- if (((*s == '\'') || (*s == '"')) /* String */
- && (Size == Byte)) {
- delim = *s++; /* Get the delimiter. */
- while (1) {
- if (*s == '\0') { /* No closing delimiter */
- Error (s-Line, NoStrEnd);
- break;
- }
- if (*s == delim) { /* End of string? */
- if (*(++s) != delim) /* Check next character. */
- break; /* End of string */
- } /* Otherwise it's an apostrophe in the string. */
- Src.Hunk = ABSHUNK; /* Absolute value */
- ObjString[nX++] = *s++; /* Current character */
- }
- } else { /* It's not a string constant. */
- s = GetField (s, SrcOp);
- ObjSrc = GetValue (SrcOp, oploc); /* Value */
- if ((Src.Hunk = Hunk2) != ABSHUNK) { /* Hunk number */
- templong = AddrCnt + nX; /* Relocatable */
- PutRel (templong, Hunk2, Size);
- }
- if (Size == 4) {
- ObjString[nX++] = (ObjSrc >> 24) & 0x00FF;
- ObjString[nX++] = (ObjSrc >> 16) & 0x00FF;
- }
- if (Size >= 2)
- ObjString[nX++] = (ObjSrc >> 8) & 0x00FF;
- ObjString[nX++] = ObjSrc & 0x00FF;
- if (Size == 2)
- templong = 0xFFFF0000L;
- else if (Size == 1)
- templong = 0xFFFFFF00L;
- if (Size < 4)
- if (((ObjSrc & templong) != 0)
- && ((ObjSrc & templong) != templong))
- Error (s-Line, SizeErr);
- }
- if (*s == ',')
- s++; /* Skip over separator. */
- }
- if ((!isspace(*s) && (*s != '\0') && (*s != ';'))
- || (SrcLoc == 0))
- Error (s-Line, OperErr); /* Statement didn't end properly. */
- AddrAdv = InstSize = nX;
- PrntAddr = MakeHunk = TRUE;
- break;
-
- case DS: /* DS */
- if (DestLoc != 0) {
- Error (DestLoc, OperErr); /* Only one operand is allowed. */
- PrntAddr = MakeHunk = TRUE;
- break;
- }
- AddrAdv = GetValue (SrcOp, SrcLoc);
- if (DefLine2 >= LineCount) {
- Error (SrcLoc, FwdRef); /* Illegal forward reference */
- AddrAdv = 0;
- }
- if (Hunk2 != ABSHUNK)
- Error (SrcLoc, AbsReq); /* Count must be absolute. */
-
- if (Size == Word) { /* Words */
- AddrCnt = AddrBndW (AddrCnt);
- AddrAdv <<= 1;
- }
- if (Size == Long) { /* Long words */
- AddrCnt = AddrBndW (AddrCnt);
- AddrAdv <<= 2;
- }
- if (Pass2 && (HunkType != HunkBSS)) { /* If this isn't */
- templong = AddrAdv; /* a BSS hunk, */
- while (templong >= 4) { /* generate zeros */
- AppendSdata (0L, 4); /* to fill the area. */
- templong -= 4;
- }
- if (templong > 0) {
- i = templong;
- AppendSdata (0L, i);
- }
- }
- PrntAddr = MakeHunk = TRUE;
- break;
-
- case Even: /* EVEN */
- FwdLim1 = FwdBranch; /* Clear forward branch controls. */
- FwdFixLimit = FwdBranchFix;
- AddrCnt = AddrBndW (AddrCnt);
- PrntAddr = MakeHunk = TRUE;
- break;
-
- case End: /* END */
- if (Pass2)
- if (SrcOp[0] != '\0')
- EndAddr = GetValue (SrcOp, SrcLoc);
- else
- EndAddr = 0;
- PrntAddr = MakeHunk = TRUE;
- break;
-
- case Xdef: /* XDEF */
- case Public: /* PUBLIC */
- if (SFormat)
- Error (OpLoc, NotSFmt); /* Not in S-format */
- s = Line + SrcLoc;
- while (!isspace(*s) && (*s != '\0') && (*s != ';')) {
- oploc = s - Line;
- s = GetField (s, SrcOp); /* Get a symbol. */
- if (ReadSymTab (SrcOp)) {
- if (!Pass2) {
- if ((Sym->Flags & 0x61) == 0) {
- Sym->Flags |= 2; /* Set XDEF flag. */
- if (OpCode[0] == 'P') {
- Sym->Flags |= 0x80; /* It's defined as PUBLIC. */
- }
- }
- } else {
- if (Sym->Defn != LineCount) /* If not PUBLIC->XREF */
- AddRef (LineCount); /* it's a reference. */
- if (Sym->Defn == NODEF)
- Error (oploc, Undef); /* It never got defined. */
- else if (Sym->Flags & 0x60)
- Error (oploc, AddrErr); /* Can't XDEF a register. */
- }
- } else if (!Pass2) { /* It's not yet defined. */
- if (OpCode[0] == 'P') { /* Treat PUBLIC as XREF. */
- AddSymTab (SrcOp, 0L, 0L ,LineCount, 0x81);
- Sym->Hunk = ~((long) Sym->Nam);
- } else {
- AddSymTab (SrcOp, 0L, CurrHunk, NODEF, 2); /* XDEF */
- }
- }
- if (*s == ',')
- s++; /* Skip over separator. */
- }
- break;
-
- case Xref: /* XREF */
- if (SFormat)
- Error (OpLoc, NotSFmt); /* Not in S-format */
- s = Line + SrcLoc;
- while (!isspace(*s) && (*s != '\0') && (*s != ';')) {
- oploc = s - Line;
- s = GetField (s, SrcOp);
- if (Pass2) {
- if (ReadSymTab (SrcOp)) {
- if (Sym->Defn != LineCount) {
- AddRef (LineCount); /* Ignore extraneous XREF. */
- }
- }
- } else {
- if (!ReadSymTab (SrcOp)) { /* Only if not defined */
- AddSymTab (SrcOp, 0L, 0L, LineCount, 1);
- Sym->Hunk = ~((long) Sym->Nam);
- }
- }
- if (*s == ',')
- s++; /* Skip over separator. */
- }
- break;
-
- case Page: /* PAGE */
- if (Pass2 && (LineCount > 1)) /* Ignore PAGE at start of file. */
- LnCnt = LnMax; /* Resume on a new page. */
- break;
-
- case DoList: /* LIST */
- ListOff = FALSE;
- if (!Pass2 && !SuppList && (IncStart != 0)) {
- IncStart = 0; /* We can't */
- if (SkipLim->Set1 != NULL) { /* skip this */
- SetFixLim = SkipLim->Set1; /* INCLUDE file */
- SetFixLim++; /* in pass 2 */
- } /* (we must */
- } /* list it). */
- break;
-
- case NoList: /* NOLIST */
- ListOff = TRUE;
- break;
-
- case Space: /* SPC */
- if (Pass2 && !ListOff && !SuppList) {
- if (SrcOp[0] != '\0')
- j = GetValue (SrcOp, SrcLoc); /* Amount to space */
- else
- j = 1; /* Default to one line. */
- for (i = 0; i < j; i++) {
- if (LnCnt >= LnMax)
- break; /* Page overflow */
- xputs (&List, "\n"); /* Space one line. */
- }
- }
- break;
-
- case Title: /* TTL */
- s = Line + SrcLoc;
- t = TTLstring;
- while (*s && (s < (TTLstring+MAXLINE)))
- *t++ = *s++; /* Get title string. */
- *t = '\0';
- if (LineCount > 1) {
- LnCnt = LnMax; /* Skip to a new page. */
- } else {
- if (Pass2) {
- xputs (&List, TTLstring);
- xputs (&List, "\n\n");
- }
- LnCnt += 2; /* Don't skip at start of file. */
- }
- break;
-
- case Cnop: /* CNOP */
- FwdLim1 = FwdBranch; /* Clear forward branch controls. */
- FwdFixLimit = FwdBranchFix;
- i = TRUE; /* "Error-free" flag */
-
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (DefLine2 >= LineCount) {
- Error (SrcLoc, FwdRef); /* Illegal forward reference */
- i = FALSE;
- }
- if (Hunk2 != ABSHUNK) {
- Error (SrcLoc, AbsReq); /* Must be absolute! */
- i = FALSE;
- }
-
- ObjDest = GetValue (DestOp, DestLoc);
- if (DefLine2 >= LineCount) {
- Error (DestLoc, FwdRef); /* Illegal forward reference */
- i = FALSE;
- }
- if (Hunk2 != ABSHUNK) {
- Error (DestLoc, AbsReq); /* Must be absolute! */
- i = FALSE;
- }
-
- templong = ObjDest;
- while ((templong > 0) && ((templong & 1) == 0))
- templong >>= 1; /* Shift out low-order zeros. */
- if ((templong != 1) || (ObjDest == 1)) {
- Error (DestLoc, OperErr); /* DestOp must be a power of 2. */
- i = FALSE;
- }
- if ((ObjSrc & 1) || (ObjSrc >= ObjDest)) {
- Error (SrcLoc, OperErr); /* SrcOp is odd or out of range. */
- i = FALSE;
- }
-
- if (i) { /* If no errors so far... */
- AddrCnt = AddrBndW (AddrCnt);
- templong = (AddrCnt & ~(ObjDest-1)) + ObjSrc;
- if (templong < AddrCnt)
- templong += ObjDest; /* We must advance to here. */
- if ((templong - AddrCnt) < MAXLINE) {
- nX = templong - AddrCnt;
- for (j = 0; j < nX; ) {
- ObjString[j++] = NOP / 256;
- ObjString[j++] = NOP & 255;
- }
- AddrAdv = InstSize = nX; /* Generate NOPs. */
- PrntAddr = MakeHunk = TRUE;
- } else {
- Error (DestLoc, OperErr); /* Too many NOPs */
- }
- }
- break;
-
- case Include: /* INCLUDE */
- if (Pass2 /* If we can skip */
- && (SkipIdx < SkipLim) /* this INCLUDE */
- && (LineCount == SkipIdx->Start)) { /* file in pass */
- LineCount = SkipIdx->Finish; /* 2, do so. */
- MacCount = SkipIdx->MCount;
- if ((sf = SkipIdx->Set1) != NULL) {
- while ((sf >= SetFixLim) && (sf->Sym != NULL)) {
- (sf->Sym)->Val = sf->Val; /* Fix up SET symbols. */
- (sf->Sym)->Hunk = sf->Hunk;
- sf--;
- }
- }
- SkipIdx++;
- break;
- }
- if ((Quiet < 0) && (InF->UPtr == 0))
- ShowLine (InF->Line); /* Show where we are. */
- s = Line + SrcLoc;
- if ((*s == '"') || (*s == '\''))
- s++; /* Ignore quotes. */
- t = tempop;
- while (!isspace(*s)
- && (*s != '"')
- && (*s != '\'')
- && (*s != '\0'))
- *t++ = *s++;
- *t = '\0';
- if (InF->UPtr == 0) {
- InF->Pos = lseek (In.fd, 0L, 1);
- InF->Pos -= In.Lim-In.Ptr; /* Position in outer file */
- }
- if (!OpenIncl (tempop, InclList)) {
- Error (SrcLoc, NoIncl); /* We couldn't open file. */
- InclErrs = TRUE;
- if (InF->UPtr == 0) {
- In.fd = open (InF->NPtr, 0);
- lseek (In.fd, InF->Pos, 0);
- In.Ptr = In.Lim = In.Buf;
- }
- break; /* Return to outer file. */
- }
- InFNum++; /* Bump nesting level. */
- if (--InF < LowInF)
- LowInF = InF;
- Heap2Space (strlen(tempop)+1); /* Check for space. */
- InF->UPtr = 0; /* It's not a user macro. */
- InF->NPtr = NextFNS; /* New stack pointer */
- strcpy (NextFNS, tempop); /* File name */
- NextFNS += strlen (tempop) + 1; /* Next available space */
- if (NextFNS > High2)
- High2 = NextFNS; /* Set high-water mark. */
- InF->NArg = -1; /* Indicate it's not a macro. */
- InF->Line = 0; /* Clear line counter. */
- InF->MCnt = MacCount;
-
- if (!Pass2 && (SuppList || ListOff) && (IncStart == 0)) {
- s = (char *) SkipLim + sizeof (struct SkipEnt);
- if (s <= (char *) SetFixLim) {
- SkipLim->Set1 = NULL; /* Save starting position */
- IncStart = LineCount; /* in case we can skip */
- IncPtr = InF; /* this file in pass 2. */
- }
- }
- break;
-
- case Set: /* SET */
- if (Label[0] == '\0')
- Error (0, NeedLab); /* Need a label */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (DefLine2 >= LineCount)
- Error (SrcLoc, FwdRef); /* Illegal forward reference */
- Src.Hunk = Hunk2;
- if (!ReadSymTab (Label)) /* Make a new entry. */
- AddSymTab (Label, ObjSrc, Src.Hunk, LineCount, 4);
- else if (Sym->Flags & 4) { /* Re-SET the symbol. */
- Sym->Val = ObjSrc; /* SET value */
- Sym->Hunk = Src.Hunk; /* Hunk number */
- Sym->Defn = LineCount; /* Statement number */
- }
- PrntAddr = MakeHunk = TRUE;
-
- if (!Pass2 && (IncStart != 0)) {
- if ((sf = SkipLim->Set1) != NULL) {
- while (sf >= SetFixLim) {
- if (sf->Sym != Sym) {
- sf--;
- } else {
- sf->Val = Sym->Val; /* Update an */
- sf->Hunk = Sym->Hunk; /* existing entry. */
- return (Set);
- }
- }
- }
- sf = SetFixLim;
- sf--;
- s = (char *) SkipLim + sizeof (struct SkipEnt);
- if (s > (char *) sf) {
- IncStart = 0; /* There's no room for set symbol. */
- if (SkipLim->Set1 != NULL) {
- SetFixLim = SkipLim->Set1;
- SetFixLim++;
- }
- } else {
- if (SkipLim->Set1 == NULL)
- SkipLim->Set1 = sf; /* First SET symbol in INCLUDE */
- sf->Sym = Sym;
- sf->Val = Sym->Val; /* Save SET symbol value */
- sf->Hunk = Sym->Hunk; /* and hunk. */
- SetFixLim = sf;
- }
- }
- break;
-
- case Macro: /* MACRO */
- if (Label[0] == '\0')
- Error (0, NeedLab); /* Need a label */
-
- s = Label;
- t = tempop;
- *t++ = ' '; /* Prepend name with a */
- while (*s) { /* blank and convert */
- *t++ = toupper (*s); /* it to upper case. */
- s++;
- }
- *t = '\0';
-
- if (!Pass2) { /* Pass 1 */
- if (!ReadSymTab (tempop)) /* Save MACRO name. */
- AddSymTab (tempop, 0L, 0L, LineCount, 8);
- Sym->Hunk = (long) AddName(Line,1); /* Save MACRO stmt. */
- } else { /* Pass 2 */
- ReadSymTab (tempop);
- if (Sym->Defn != LineCount) {
- Error (LabLoc, DupMac); /* Duplicate MACRO */
- AddRef (LineCount);
- }
- WriteListLine (&List); /* Echo MACRO. */
- }
-
- i = 0; /* IF nest counter */
- while (1) { /* Process macro body. */
- if (LineParts (dummy)) {
- Error (OpLoc, NoENDM); /* Premature EOF */
- i = 0;
- break;
- }
- if ((i += CountNest (OpCode)) < 0) {
- Error (OpLoc,ManyENDC); /* Unmatched ENDC */
- i = 0;
- }
- if (!Pass2)
- AddName (Line, 2); /* Store a line. */
- if (strcmp (OpCode, "ENDM") == 0)
- break; /* Main program echoes ENDM. */
- if (Pass2)
- WriteListLine (&List); /* Echo a line. */
- }
- if (i > 0)
- Error (OpLoc, NoENDC); /* ENDC is missing! */
-
- break;
-
- case IfEQ: /* IFEQ */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (ObjSrc != 0)
- SkipNest++; /* Skip to the next ENDC. */
- break;
-
- case IfNE: /* IFNE */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (ObjSrc == 0)
- SkipNest++;
- break;
-
- case IfGT: /* IFGT */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (ObjSrc <= 0)
- SkipNest++;
- break;
-
- case IfGE: /* IFGE */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (ObjSrc < 0)
- SkipNest++;
- break;
-
- case IfLT: /* IFLT */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (ObjSrc >= 0)
- SkipNest++;
- break;
-
- case IfLE: /* IFLE */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (ObjSrc > 0)
- SkipNest++;
- break;
-
- case IfC: /* IFC */
- if (strcmp (SrcOp, DestOp) != 0)
- SkipNest++;
- break;
-
- case IfNC: /* IFNC */
- if (strcmp (SrcOp, DestOp) == 0)
- SkipNest++;
- break;
-
- case IfD: /* IFD */
- if (ReadSymTab (SrcOp))
- AddRef (LineCount);
- if (DefLine2 > LineCount)
- SkipNest++;
- break;
-
- case IfND: /* IFND */
- if (ReadSymTab (SrcOp))
- AddRef (LineCount);
- if (DefLine2 <= LineCount)
- SkipNest++;
- break;
-
- case EndC: /* ENDC */
- break; /* LineParts will take care of it. */
-
- case Section: /* SECTION */
- tempop[0] = '\0';
- s = Line + DestLoc + strlen (DestOp); /* Check for flags. */
- if (*s == ',') {
- s++;
- GetField (s, tempop); /* Get specification. */
- }
- DoSection (SrcOp, SrcLoc, DestOp, DestLoc, tempop, j);
- break;
-
- case CSeg: /* CODE */
- DoSection (SrcOp, SrcLoc, "CODE", OpLoc, DestOp, DestLoc);
- break; /* Treat as SECTION. */
-
- case DSeg: /* DATA */
- DoSection (SrcOp, SrcLoc, "DATA", OpLoc, DestOp, DestLoc);
- break; /* Treat as SECTION. */
-
- case BSS: /* BSS */
- DoSection (SrcOp, SrcLoc, "BSS", OpLoc, DestOp, DestLoc);
- break; /* Treat as SECTION. */
-
- case Idnt: /* IDNT */
- s = Line + SrcLoc;
- if ((*s == '"') || (*s == '\''))
- s++; /* Ignore quotes. */
- t = IdntName;
- while (!isspace(*s)
- && (*s != '"')
- && (*s != '\'')
- && (*s != '\0'))
- *t++ = *s++;
- *t = '\0';
- break;
-
- case DCB: /* DCB */
- if ((Size == Word) || (Size == Long))
- AddrCnt = AddrBndW (AddrCnt);
- DupFact = GetValue (SrcOp, SrcLoc); /* Replication factor */
- if (DefLine2 >= LineCount) {
- Error (SrcLoc, FwdRef); /* Illegal forward reference */
- DupFact = 0;
- }
- if (Hunk2 != ABSHUNK) {
- Error (SrcLoc, AbsReq); /* Must be absolute! */
- DupFact = 0;
- }
- ObjDest = GetValue (DestOp, DestLoc); /* Value to replicate */
- Dest.Hunk = Hunk2;
- if (Size == 4) {
- ObjString[nX++] = (ObjDest >> 24) & 0x00FF;
- ObjString[nX++] = (ObjDest >> 16) & 0x00FF;
- }
- if (Size >= 2)
- ObjString[nX++] = (ObjDest >> 8) & 0x00FF;
- ObjString[nX++] = ObjDest & 0x00FF;
-
- AddrAdv = InstSize = nX;
- if (Dest.Hunk != ABSHUNK) { /* Relocatable */
- templong = AddrCnt;
- for (i = 0; i < DupFact; i++) {
- PutRel (templong, Hunk2, Size); /* Generate a relocation */
- templong += nX; /* entry for each constant. */
- }
- }
- PrntAddr = MakeHunk = TRUE;
- break;
-
- case Equr: /* EQUR */
- if ((i = IsRegister (SrcOp, strlen (SrcOp))) < 0)
- Error (SrcLoc, AddrErr); /* Not a valid register. */
- if (Label[0] == '\0')
- Error (0, NeedLab); /* Need a label */
- else {
- if (!ReadSymTab (Label)) /* Make a new entry. */
- AddSymTab (Label, (long) i, 0L, LineCount, 0x20);
- GotEqur = TRUE; /* We have at least one EQUR. */
- }
- break;
-
- case Reg: /* REG */
- if (Label[0] == '\0')
- Error (0, NeedLab); /* Need a label */
- else {
- if ((i = GetMultReg (SrcOp, SrcLoc)) == 0) {
- Error (SrcLoc, OperErr);
- } else {
- if (!ReadSymTab (Label)) { /* Make a new entry. */
- AddSymTab (Label, (long) i, 0L, LineCount, 0x40);
- GotEqur = TRUE; /* We have at least one EQUR. */
- }
- }
- }
- break;
-
- case Near: /* NEAR */
- if (SrcOp[0] == '\0') {
- SmallData = 4; /* Default to register A4. */
- } else { /* Get register specification. */
- SmallData = IsRegister (SrcOp, strlen (SrcOp)) - 8;
- if ((SmallData < 0) || (SmallData > 6)) {
- Error (SrcLoc,AddrErr); /* It's not a valid register. */
- SmallData = -1; /* Disable small-data model. */
- }
- }
- AnyNear = TRUE; /* Remember that we use small data somewhere. */
- break;
-
- case Far: /* FAR */
- SmallData = -1; /* Reset small-data model flag. */
- break;
-
- default:
- break;
- }
-
- return (Dir);
- }
-
-
-
- DoSection (name, nameloc, type, typeloc, flags, flagloc)
- char *name, *type, *flags;
- int nameloc, typeloc, flagloc;
- /* Processes SECTION directive or equivalent. */
- {
- static long HunkPos; /* Seek address of start of section */
- register char *s, *t;
- long newflags, templong;
- char tempop[MAXLINE];
-
- PrntAddr = TRUE;
- if (SFormat)
- Error (OpLoc, NotSFmt); /* Not in S-format */
-
- if (HunkType != HunkNone) {
- FwdLim1 = FwdBranch; /* Clear forward branch controls. */
- FwdFixLimit = FwdBranchFix;
- }
-
- for (s = type; *s; s++) /* Convert section type */
- *s = toupper (*s); /* to upper case. */
- if ((type[0] == '\0') || (strcmp (type, "CODE") == 0))
- newflags = HunkCode; /* Code section */
- else if (strcmp (type, "DATA") == 0)
- newflags = HunkData; /* Data section */
- else if (strcmp (type, "BSS") == 0)
- newflags = HunkBSS; /* BSS section */
- else {
- Error (typeloc, OperErr); /* Invalid type */
- strcpy (type, "CODE");
- newflags = HunkCode; /* Make it CODE. */
- }
- newflags <<= 16; /* Shift to high-order 16 bits. */
-
- if (flags[0]) {
- for (s = flags; *s; s++) /* Convert flags */
- *s = toupper (*s); /* to upper case. */
- if (strcmp (flags, "CHIP") == 0)
- newflags |= MEMF_CHIP; /* CHIP memory */
- else if (strcmp (flags, "FAST") == 0)
- newflags |= MEMF_FAST; /* FAST memory */
- else
- Error (flagloc, OperErr); /* Invalid - ignore. */
- }
-
- templong = (newflags & 0xFFFF0000) >> 16;
- sprintf (tempop," %4x",HunkSeq++); /* Make section name unique. */
- s = name;
- if ((*s == '"') || (*s == '\''))
- s++; /* Ignore quotes. */
- t = tempop + 6;
- while (!isspace(*s)
- && (*s != '"')
- && (*s != '\'')
- && (*s != '\0'))
- *t++ = *s++; /* Concatenate section name. */
- *t = '\0';
-
- if (ReadSymTab (tempop)) { /* Scan for section name. */
- if (HunkType == HunkNone) {
- SectLine = 1; /* Start of first section */
- } else {
- if (Pass2) {
- AddRef (LineCount);
- DumpSdata (&Srec); /* Finish the previous hunk. */
- if (!MakeHunk) { /* If it was a null hunk, */
- if (Srec.Ptr > Srec.Buf) /* overwrite it. */
- write (Srec.fd, Srec.Buf, Srec.Ptr - Srec.Buf);
- lseek (Srec.fd, HunkPos, 0);
- Srec.Ptr = Srec.Buf;
- }
- } else {
- AddrCnt = AddrBndL (AddrCnt); /* Finish on long word. */
- }
- if (AddrCnt > OrgHigh)
- Sect->Val = AddrCnt; /* End of old section */
- else
- Sect->Val = OrgHigh; /* We've ORGed higher. */
- SectLine = LineCount; /* Start of new section */
- }
- Sect = Sym; /* Point to new section. */
- AddrCnt = SectStart = Sym->Val; /* Continuation */
- OrgHigh = 0L;
- OrgFlag = FALSE;
- TempAddr = StartAddr = AddrCnt;
- CurrHunk = Sym->Hunk & 0x0000FFFFL; /* Hunk number */
- HunkType = (Sym->Hunk & 0x3FFF0000L) >> 16; /* Type */
- HunkFlags = Sym->Hunk & 0xC0000000L; /* Flags */
- if (Pass2 && !SFormat) { /* Start a new hunk. */
- HunkPos = lseek (Srec.fd, 0L, 1);
- HunkPos += Srec.Ptr - Srec.Buf; /* It starts here. */
- templong = HunkName;
- xputl (&Srec, templong);
- if (tempop[6])
- DumpName (&Srec, &tempop[6], 0L); /* Hunk name */
- else
- DumpName (&Srec, " ", 0L);
- xputl (&Srec, HunkType | HunkFlags); /* Hunk type */
- LenPtr = Srec.Ptr; /* Pointer to hunk length */
- LenPos = lseek (Srec.fd, 0L, 1);
- LenPos += LenPtr-Srec.Buf; /* Hunk length goes here. */
- xputl (&Srec, 0L); /* For now, set it to zero. */
- }
- MakeHunk = FALSE; /* We don't have anything yet. */
- if (AnyNear && (CurrHunk > 1))
- Error (OpLoc, ManySect); /* Too many hunks for small data! */
- return;
- }
-
- AddrCnt = AddrBndL (AddrCnt); /* Finish on long word bounary. */
-
- if (Pass2) {
- Error (OpLoc, ManySect); /* Table overflowed in pass 1! */
- return;
- }
- if (NextHunk >= ABSHUNK) /* Set up a new table entry. */
- return; /* Section table overflow */
-
- if (HunkType != HunkNone) {
- if (AddrCnt > OrgHigh)
- Sect->Val = AddrCnt; /* End of old section */
- else
- Sect->Val = OrgHigh; /* We've ORGed higher. */
- SectLine = LineCount; /* Starting line number */
- } else {
- SectLine = 1; /* Start of first section */
- }
- AddrCnt = SectStart = OrgHigh = 0L; /* Reset location counter. */
- OrgFlag = FALSE;
- TempAddr = StartAddr = AddrCnt;
- HunkType = (newflags & 0x3FFF0000L) >> 16; /* Type */
- HunkFlags = newflags & 0xC0000000L; /* Flags */
- CurrHunk = NextHunk++; /* Bump next hunk number. */
- newflags |= CurrHunk; /* Add hunk number to flags. */
- AddSymTab (tempop, 0L, newflags, LineCount, 16); /* New entry */
- Sect = Sym; /* Pointer to new entry */
- MakeHunk = FALSE; /* We don't have anything yet. */
- if (AnyNear && (CurrHunk > 1))
- Error (OpLoc, ManySect); /* Too many hunks for small data! */
- return;
- }
-